package com.zhc.tools.common.util;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期助手类，实现：日期加减计算、日期与字符串互相转换。
 * 
 * @author zhc
 */
public class DateHelper {

    /**
     * 10 分钟的毫秒数
     */
    public static final long TEN_MINUTES = 10 * 60 * 1000;
    /**
     * 24 小时的毫秒数
     */
    public static final long ONE_DAY = 24 * 60 * 60 * 1000;

    /** 日期格式：yyyy-MM-dd */
    public static final String DATE_FORMAT = "yyyy-MM-dd";
    /** 日期格式：yyyyMMdd */
    public static final String DATE_FORMAT_NO_SPLIT = "yyyyMMdd";
    /** 日期格式：yyyy-MM-dd HH:mm:ss */
    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    /** 日期格式：yyyy-MM-dd HH:mm:ss.SSS */
    public static final String DATE_TIME_MS_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";


    /**
     * 调整日期
     * @return
     */
    public static Date add(final Date date, Integer field, Integer amount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        calendar.add(field, amount);

        return calendar.getTime();
    }


    /**
     * 日期调整天数
     * @param date 初始日期
     * @param days 天数
     * @return
     */
    public static Date addDate(final Date date, Integer days) {
        return DateHelper.add(date, Calendar.DATE, days);
    }


    /**
     * 根据相应格式转换日期
     * @param date 初始日期
     * @param format 日期格式，若为空则以 yyyy-MM-dd 进行转换
     * @return 字符串
     */
    public static String format(Date date, String format) {
        if (date == null) {
            return "";
        }

        if (isEmpty(format)) {
            format = DATE_FORMAT;
        }

        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    private static boolean isEmpty(String str) {
        return str == null || str.trim().length() == 0;
    }


    /**
     * 根据 yyyy-MM-dd 格式进行转换日期
     * @param date 初始日期
     * @return 字符串
     */
    public static String formatDate(Date date) {
        return format(date, DATE_FORMAT);
    }


    /**
     * 得到当前日期的 yyyy-MM-dd 字符串
     * @return
     */
    public static String today() {
        return formatDate(new Date());
    }


    /**
     * 根据 yyyy-MM-dd HH:mm:ss 格式进行转换日期
     * @param date 初始日期
     * @return 字符串
     */
    public static String formatDateTime(Date date) {
        return format(date, DATE_TIME_FORMAT);
    }


    /**
     * 根据 yyyy-MM-dd HH:mm:ss.SSS 格式进行转换日期
     * @param date 初始日期
     * @return 字符串
     */
    public static String formatDateTimeMs(Date date) {
        return format(date, DATE_TIME_MS_FORMAT);
    }

    /**
     * 将 Object 转换为 Date对象
     * @param object
     * @return
     */
    public static Date getDateValue(Object object) {
        return null == object ? null : (Date) object;
    }

    /**
     * 按照指定格式转换指定日期字符串
     * @param dateString 日期字符串
     * @param format 日期格式
     * @return 日期对象
     */
    public static Date parseDate(String dateString, String format) {
        if (isEmpty(format)) {
            return null;
        }

        try {
            return new SimpleDateFormat(format).parse(dateString);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 根据 yyyy-MM-dd 转换指定日期字符串
     * @param dateString 日期字符串
     * @return 日期对象
     */
    public static Date parseDate(String dateString) {
        return DateHelper.parseDate(dateString, DATE_FORMAT);
    }

    /**
     * 根据 yyyy-MM-dd HH:mm:ss 转换指定日期字符串
     * @param dateString 日期字符串
     * @return 日期对象
     */
    public static Date parseDateTime(String dateString) {
        return DateHelper.parseDate(dateString, DATE_TIME_FORMAT);
    }


    /**
     * 将长整型转换为日期对象
     * @param date 长整型
     * @return
     */
    public static Date toDate(Long date) {
        if (date == null) {
            return null;
        }
        return new Date(date);
    }

    /**
     * 根据指定日期格式获取当前日期的字符串
     * @param dateString 日期格式，若为空 则默认为 yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String getCurrentDateStr(String dateString) {
        if (isEmpty(dateString)) {
            dateString = DATE_TIME_FORMAT;
        }
        return format(new Date(), dateString);
    }

    /**
     * 根据所给时间字符串时间对象，获取时将与服务器当前时间作对比，相差不能超过10分钟，否则以服务器时间为准
     * @param operateTimeStr 所给时间字符串
     * @return 时间对象
     */
    public static Date getServerTime(String operateTimeStr) {
        Date serverTime = new Date();
        if (isEmpty(operateTimeStr)) {
            return serverTime;
        }

        Date operateTime = parseDate(operateTimeStr, DATE_TIME_FORMAT);

        if (operateTime == null) {
            operateTime = DateHelper.parseDate(operateTimeStr, DATE_TIME_MS_FORMAT);
        }

        Long interval = operateTime.getTime() - serverTime.getTime();
        if (operateTime.after(serverTime) && TEN_MINUTES < interval) {
            return serverTime;
        } else if (operateTime.before(serverTime) && ONE_DAY < Math.abs(interval)) {
            return serverTime;
        } else {
            return operateTime;
        }
    }

}
